DevSecOps práctico con Sigstore y cosign

Candado metálico sobre teclado representando firma digital y seguridad en el pipeline

Sigstore y su CLI cosign llevan dos años dejando de ser experimento. Hoy hay grandes proyectos — Kubernetes, Istio, NPM con provenance, Python con PEP 740 — que firman sus artefactos con la cadena Sigstore. Pero entre “existe” y “lo usa mi equipo bien” sigue habiendo un salto. Este artículo es sobre cerrar ese salto: firmar imágenes y binarios de forma que la firma signifique algo y no se convierta en otra casilla en un checklist.

De qué se ocupa Sigstore realmente

Sigstore es un conjunto de tres piezas que encajan:

  • cosign: la CLI que firma y verifica artefactos (imágenes OCI, blobs, SBOMs).
  • Fulcio: una autoridad certificadora que emite certificados de corta vida (unos 10 minutos) vinculados a una identidad OIDC — tu cuenta de GitHub, Google, o tu proveedor corporativo.
  • Rekor: un log transparente e inmutable donde las firmas se registran con un timestamp auditado.

La magia práctica es que no necesitas gestionar claves privadas persistentes. Firmas con una identidad (OIDC), obtienes un certificado efímero, firmas, el certificado expira, y el registro queda en Rekor para que cualquiera verifique la firma después.

Este modelo keyless elimina la mayor fuente de incidentes de firma: claves comprometidas o perdidas. A cambio, introduce dependencia de la infraestructura pública de Sigstore — o la necesidad de desplegar tu propia instancia si tienes requisitos estrictos.

Firmar una imagen OCI

El caso de uso más común: firmar una imagen Docker/OCI tras construirla.

# Build + push como siempre
docker build -t registry.example.com/myapp:1.2.3 .
docker push registry.example.com/myapp:1.2.3

# Firma keyless con cosign (usa OIDC automáticamente)
cosign sign registry.example.com/myapp:1.2.3

Cosign detecta el entorno (GitHub Actions, Gitea Actions, GitLab CI, local) y obtiene el token OIDC apropiado. La firma se adjunta al registro como artefacto adicional (manifiesto referenciado), no como una etiqueta distinta.

Verificar:

cosign verify registry.example.com/myapp:1.2.3 \
  --certificate-identity=ci@example.com \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com

La verificación no es “¿tiene firma?”. Es “¿tiene firma de la identidad que espero?”. Sin la parte de identidad, la firma es decorativa.

Integrar en un pipeline real

Tres patrones que funcionan en equipos con volumen:

  • Firma automática en CI: cada build exitoso firma. El workflow tiene permiso OIDC al emisor Sigstore. Si el build pasa, firma es gratis.
  • Policy en admission controller: Kyverno o Gatekeeper en Kubernetes rechazan pods cuya imagen no esté firmada por identidades autorizadas.
  • Verificación en GitOps: Flux y Argo CD pueden verificar firmas antes de reconciliar. La firma se convierte en gatekeeper real.

El error común es firmar pero no verificar en despliegue. Firma sin verificación es trabajo sin beneficio.

Firma de SBOMs y provenance

Además de imágenes, Sigstore firma:

  • SBOMs (Software Bill of Materials) generados con Syft.
  • Provenance SLSA generado por el builder — una prueba de cómo se construyó la imagen, qué commit, qué workflow, qué herramientas.
  • Binarios directos con cosign sign-blob.

Para cumplir SLSA Level 3 necesitas provenance firmada no-falsificable. Sigstore es el mecanismo natural para conseguirla sin montar toda una infraestructura propia.

Claves vs. keyless: cuándo usar cuál

No siempre vas a querer OIDC keyless:

  • Keyless: por defecto, menos operaciones, menos riesgo de claves comprometidas, dependencia de Sigstore público.
  • Keypair: clave persistente (RSA o ECDSA), totalmente offline, tú gestionas la custodia. Útil para air-gapped o requisitos estrictos.
  • KMS: clave en HashiCorp Vault, AWS KMS, GCP KMS, etc. Buen balance entre gestión centralizada y firma verificable.

En la mayoría de equipos cloud-native, keyless es suficiente y operacionalmente más simple. En regulados, KMS suele ser el camino.

Sigstore privado: cuándo tiene sentido

Sigstore público tiene límites: uso compartido, dependencia de infraestructura ajena, identidades OIDC expuestas en Rekor público. Para ciertos casos tiene sentido desplegar scaffolding — una instancia propia de Fulcio + Rekor.

Casos típicos:

  • Regulados donde los metadatos de firma son sensibles.
  • Air-gapped o redes donde no hay acceso a Sigstore público.
  • Alta volumetría que justifica costes operativos.

Para todos los demás, el público es más que suficiente y mucho menos trabajo.

Errores comunes

He visto equipos estropear DevSecOps con firmas de estas formas:

  • Firmar todo, verificar nada. La firma sin verificación es teatro.
  • Aceptar cualquier identidad. Verificar “tiene firma” sin validar quién firmó es casi equivalente a no firmar.
  • Olvidar rotar. En el modelo keypair, si no rotas las claves anuales, pierdes el beneficio.
  • No guardar el log de Rekor. Para auditoría a largo plazo, necesitas el UUID de Rekor entry como evidencia.
  • Falta de runbook cuando falla. Si Sigstore público tiene un incidente, tu CI se para. Ten plan B.

Checklist mínima

Un equipo que quiera empezar con Sigstore sin complicaciones:

  • Firma en CI keyless sobre imágenes principales.
  • Verificación en despliegue (Kyverno, Flux, Argo).
  • Lista de identidades autorizadas versionada en Git.
  • Alerta si una imagen sin firma llega a producción.
  • Revisión trimestral de qué se firma y qué no.

Con eso ya estás por delante de la media.

Conclusión

Sigstore pasó de proyecto experimental a infraestructura defacto para firmar software. La fricción de adopción ha caído. Lo que queda es integrarlo de forma que signifique algo — verificando de verdad, con identidades bien definidas, y con runbooks claros cuando falla. Firmar por firmar es peor que no firmar: te da la ilusión de seguridad sin los beneficios. Bien aplicado, cierra una de las puertas que los atacantes de supply chain llevan años explotando.

Síguenos en jacar.es para más sobre DevSecOps, supply chain y despliegues menos vulnerables.

Entradas relacionadas